package com.spring.lesson001.demo12.cglib.eg4;

import org.junit.Test;
import org.springframework.cglib.proxy.*;

import java.lang.reflect.Method;

/**
 * @author vhans
 */
public class CglibTest {
    @Test
    public void test5() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Service4.class);
        // 创建两个callback
        Callback[] callbacks = {
                // 用来拦截insert
                new MethodInterceptor() {
                    @Override
                    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                        long startTime = System.nanoTime();
                        Object result = methodProxy.invokeSuper(o, objects);
                        long endTime = System.nanoTime();
                        System.out.println("方法" + method.getName() + "耗时(纳秒):" + (endTime - startTime));
                        return result;
                    }
                },
                // 用来拦截get
                new FixedValue() {
                    @Override
                    public Object loadObject() throws Exception {
                        return "Vhans";
                    }
                }
        };
        // 使用setCallbacks传递callbacks数组
        enhancer.setCallbacks(callbacks);
        // 设置过滤器并给出过滤方式
        enhancer.setCallbackFilter(new CallbackFilter() {
            @Override
            public int accept(Method method) {
                String methodName = method.getName();
                // 返回的数字对应数组下标
                return methodName.startsWith("insert") ? 0 : 1;
            }
        });
        Service4 proxy = (Service4) enhancer.create();
        System.out.println("========");
        proxy.insert1();
        System.out.println("========");
        proxy.insert2();
        System.out.println("========");
        System.out.println(proxy.get1());
        System.out.println("========");
        System.out.println(proxy.get2());

    }

    // 对案例5的优化
    @Test
    public void test6() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Service4.class);
        // 创建两个callback
        Callback costTimeCallback = (MethodInterceptor) (Object o, Method method, Object[] objects, MethodProxy methodProxy) -> {
            long startTime = System.nanoTime();
            Object result = methodProxy.invokeSuper(o, objects);
            long endTime = System.nanoTime();
            System.out.println("方法" + method.getName() + "耗时(纳秒):" + (endTime - startTime));
            return result;
        };
        Callback fixedValueCallback = (FixedValue) () -> "Vhans";
        // cglib中有个CallbackHelper类，可以对案例5的代码进行有环，CallbackHelper类相当于对一些代码进行了封装，方便实现案例5的需求。
        CallbackHelper callbackHelper = new CallbackHelper(Service4.class, null) {
            @Override
            protected Object getCallback(Method method) {
                return method.getName().startsWith("insert") ? costTimeCallback : fixedValueCallback;
            }
        };
        enhancer.setCallbacks(callbackHelper.getCallbacks());
        // 注意要设置过滤器为CallbackHelper对象
        enhancer.setCallbackFilter(callbackHelper);
        Service4 proxy = (Service4) enhancer.create();
        System.out.println("========");
        proxy.insert1();
        System.out.println("========");
        proxy.insert2();
        System.out.println("========");
        System.out.println(proxy.get1());
        System.out.println("========");
        System.out.println(proxy.get2());
    }
}
